'''
Created on May 16, 2010

iur - Universal Web Remote targetted for iphone
Copyright (C) 2010 forteresce@gmail.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

'''
import bottle
from bottle import route, run, static_file, view
import os
import shutil
from model.playerObject import PlayerObject
from dbus.exceptions import DBusException
from util.mpris import Mpris
import player
from player import *
import sys

ROOT = os.path.dirname(os.path.abspath(__file__))
COVERPATH = os.path.join(ROOT, './static/images/cover')
eventHandler = None
collectionHandler = None

def listPlayers():
    mpris = Mpris()    
    players_running = mpris.get_mpris2_buses()
    players = []
    for playerBus in players_running:
        player = PlayerObject(playerBus, mpris.get_friendly_name(playerBus))
        players.append(player)
    return players

@route('/player/list', method='POST')
def playerList():    
    players = listPlayers()
    return '{ "players": [' + ",".join([str(player.toJson()) for player in players]) + "]}"

@route('/player/:playerBus', method='POST')
def player_select(playerBus):
    global eventHandler, collectionHandler
    eventHandler = GenericEventHandler(playerBus)
    exec('collectionHandler = %s%s()' % (Mpris().get_friendly_name(playerBus), player.COLLECTION_HANDLER ), globals(), globals())
    return getCurrentSongJson()

@route('/stats/currentSong', method='POST')
def stats_currentSong():
    return getCurrentSongJson()

#===================== Player Event Handling ========================
@route('/playback/:command', method='POST')
def playback(command):
    try:
        exec('eventHandler.%s()' % command, globals(), globals())
    except DBusException as dbe:
        return getMessageJson(dbe.get_dbus_message())
    return getCurrentSongJson()

@route('/queue/play/:song', method='POST')
def addToQueue(song):
    try:
        eventHandler.playSong(song)
    except DBusException as dbe:
        return getMessageJson(dbe.get_dbus_message())
    return getCurrentSongJson()

@route('/queue/add/:song', method='POST')
def addToQueue(song):
    try:
        eventHandler.addSongToQueue(song)
    except DBusException as dbe:
        return getMessageJson(dbe.get_dbus_message())
    return getCurrentSongJson()

@route('/volume/:command', method='POST')
def volume(command):
    exec('volume = eventHandler.volume%s()' % command, globals(), globals())
    return '{"volume": "%s"}' % volume

@route('/seek/:command', method='POST')
def seek(command):
    exec('position = eventHandler.seek%s()' % command, globals(), globals())
    return '{"position": "%s"}' % position

@route('/random/get', method='POST')
def getRandom():
    return ('{"random": %s}' % eventHandler.getShuffle()).lower()

@route('/random/set', method='POST')
def setRandom():
    currentValue = eventHandler.getShuffle()
    eventHandler.setShuffle(not currentValue)
    return ('{"random": %s}' % (not currentValue)).lower()

#===================== Playlist Collection Handling ========================
@route('/playlist', method='POST')
def listPlaylists():
    playlists = eventHandler.getPlayerPlaylists()
    return '{ "playlists": [' + ",".join([str(playlist.toJson()) for playlist in playlists]) + ']}'

@route('playlist/:id', method='POST')
def setPlaylist(id):
    eventHandler.setCurrentPlaylist(id)
    return getCurrentSongJson()

#===================== Player Collection Handling ========================
@route('/albums/', method='POST')
def albums():
    albums=collectionHandler.getAlbums()
    albumsSorted = sorted(albums, key=lambda album: album.title.strip('"<>').capitalize())
    return '{ "albums": [' + ",".join([str(album.toJson()) for album in albumsSorted]) + ']}'

@route('/albums/:startsWith', method='POST')
def albums(startsWith):
    albums=collectionHandler.getAlbums(startsWith)
    return '{ "albums": [' + ",".join([str(album.toJson()) for album in albums]) + ']}'

@route('/songs/:albumId', method='POST')
def songs(albumId):
    songs = collectionHandler.getSongsInAlbum(albumId)
    return '{ "songs": [' + ",".join([str(song.toJson()) for song in songs]) + ']}'

#===================== Static File Handling ========================        
    
@route('/')
def index():
    return static_file('index.html', root=os.path.join(ROOT, './static/html/'))

@route('/js/:filename#.*#')
def static_js(filename):
    return static_file(filename, root=os.path.join(ROOT, './static/js/'))

@route('/jqt/:filename#.*#')
def static_jqt(filename):
    return static_file(filename, root=os.path.join(ROOT, './static/jqt/'))

@route('/images/:filename#.*#')
def static_images(filename):
    return static_file(filename, root=os.path.join(ROOT, './static/images/'))

@route('/icons/:filename#.*#')
def static_images(filename):
    return static_file(filename, root=os.path.join(ROOT, './static/images/TWG Retina Icons/'))

@route('/css/:filename')
def static_css(filename):
    return static_file(filename, root=os.path.join(ROOT, './static/css/'))

@route('/:filename#.*\.manifest#')
def static(filename):
    static_file(filename, root=os.path.join(ROOT, './static/'), mimetype='text/cache-manifest')
    
#==================Miscellaneous=================================================
def getStaticCoverUrl(coverArtFile):
    if not os.path.exists(coverArtFile):
        #TODO Send default cover art
        return
    if not os.path.exists(os.path.join(COVERPATH, os.path.basename(coverArtFile))):
        shutil.copy(coverArtFile, COVERPATH)
    return os.path.basename(coverArtFile)

def getCurrentSongJson():
    if not eventHandler:
        return getMessageJson('No player selected. Please select player on main screen.')
    song = eventHandler.getCurrentSong()
    
    if not song:
        return getMessageJson('Not currently playing')
    song.setCoverArtUrl(getStaticCoverUrl(song.coverArtFile))
    return '{"song": ' + song.toJson() + '}'

def getMessageJson(message):
    return '{"message": "%s"}' % message
#==================Simple To Std Error Log =============================
def log(str):
    sys.stderr.write('%s\n' % str)


def close_cliked(widget,data=None):
    sys.exit()

    
def start():
    bottle.TEMPLATE_PATH = [os.path.join(ROOT, './views/')]
    run(host='0.0.0.0', port=7070)

